﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using UIDesigner.DesignContainers.Bases;

namespace UIDesigner.SurfaceProperties
{
    public enum SurfaceBindPropertyKind
    {
        BindOption,
        BindState,
        PreBindOptions,
        PostBindExistingOptions,
        PostBindNewOptions
    }

    public class SurfaceBindState : SurfaceStateBase
    {
        private SurfaceBindPropertyKind m_eKind;
        private AFDesignerHost m_objHost;
        private IBaseObjectControl m_objControl;
        private SurfacePropertiesBase m_objSurrogateProperties;

        public SurfaceBindState(SurfaceBindPropertyKind eKind, AFDesignerHost objHost, IBaseObjectControl objControl)
        {
            m_eKind = eKind;
            m_objHost = objHost;
            m_objControl = objControl;
        }

        public SurfaceBindState(SurfaceBindPropertyKind eKind, AFDesignerHost objHost, IBaseObjectControl objControl, SurfacePropertiesBase objSurrogateProperties)
        {
            m_eKind = eKind;
            m_objHost = objHost;
            m_objControl = objControl;
            m_objSurrogateProperties = objSurrogateProperties;
        }

        public override IBaseObjectControl BaseObjectControl
        {
            get 
            {
                return m_objControl;
            }
        }

        public override string Name
        {
            get
            {
                return "Surface Bind State Designer";
            }
        }

        public override string ToString()
        {
            return Enum.GetName(typeof(SurfaceBindPropertyKind), m_eKind);
        }

        public override int Kind
        {
            get 
            {
                return (int)m_eKind;
            }
        }

        public override AFDesignerHost Host
        {
            get 
            {
                return m_objHost;
            }
        }

        public override Type KindType
        {
            get 
            {
                return typeof(SurfaceBindPropertyKind);
            }
        }
    }

    public class SurfaceBindDescriptor : PropertyDescriptor
    {
        private AFDesignerHost m_objHost;
        private SurfaceBindPropertyKind m_eKind;
        private IBaseObjectControl m_objControl;
        private SurfacePropertiesBase m_objSurrogateProperties;

        public SurfaceBindDescriptor(AFDesignerHost objHost, IBaseObjectControl objControl, SurfaceBindPropertyKind eKind, Attribute[] rgAttributes) : base(Enum.GetName(typeof(SurfaceBindPropertyKind), eKind), rgAttributes)
		{
            m_objHost = objHost;
            m_eKind = eKind;
            m_objControl = objControl;
        }

        public SurfaceBindDescriptor(AFDesignerHost objHost, IBaseObjectControl objControl, SurfaceBindPropertyKind eKind, Attribute[] rgAttributes, SurfacePropertiesBase objSurrogateProperties) : base(Enum.GetName(typeof(SurfaceBindPropertyKind), eKind), rgAttributes)
		{
            m_objHost = objHost;
            m_eKind = eKind;
            m_objControl = objControl;
            m_objSurrogateProperties = objSurrogateProperties;
        }

        private SurfacePropertiesBase SurfaceProperties
        {
            get
            {
                if (m_objSurrogateProperties == null)
                {
                    return m_objHost.SurfacePropertiesSet[m_objControl];
                }
                else
                {
                    return m_objSurrogateProperties;
                }
            }
        }

		public override bool CanResetValue(object component)
		{
			return true;
		}

		public override Type ComponentType
		{
			get 
            {
                return m_objHost.RootComponent.GetType(); 
            }
		}

		public override object GetValue(object component)
		{
            switch (m_eKind)
            {
                case SurfaceBindPropertyKind.BindOption:
                    return this.SurfaceProperties.BindProperties.BindStateOptions;  
                case SurfaceBindPropertyKind.PreBindOptions:
                    return this.SurfaceProperties.BindProperties.PreBindOptions;
                case SurfaceBindPropertyKind.PostBindExistingOptions:
                    return this.SurfaceProperties.BindProperties.PostBindExistingOptions;
                case SurfaceBindPropertyKind.PostBindNewOptions:
                    return this.SurfaceProperties.BindProperties.PostBindNewOptions;
                case SurfaceBindPropertyKind.BindState:
                    return new SurfaceBindState(m_eKind, m_objHost, m_objControl, m_objSurrogateProperties);  
                default:
                    Debugger.Break();
                    return null;
            }
		}

		public override bool IsReadOnly
		{
			get 
            {
                return false;
            }
		}

		public override Type PropertyType
		{
			get 
            {
                switch (m_eKind)
                {
                    case SurfaceBindPropertyKind.BindOption:
                        return typeof(BindStateOptions);
                    case SurfaceBindPropertyKind.PreBindOptions:
                        return typeof(PreBindOptions);
                    case SurfaceBindPropertyKind.PostBindExistingOptions:
                        return typeof(PostBindExistingOptions);
                    case SurfaceBindPropertyKind.PostBindNewOptions:
                        return typeof(PostBindNewOptions); 
                    case SurfaceBindPropertyKind.BindState:
                        return typeof(SurfaceBindState);
                    default:
                        Debugger.Break();
                        return null;
                }
            }
		}

		public override void ResetValue(object component)
		{
			
		}

		public override void SetValue(object component, object value)
		{
            switch (m_eKind)
            {
                case SurfaceBindPropertyKind.BindOption:

                    this.SurfaceProperties.BindProperties.BindStateOptions = (BindStateOptions) value;
                    break;

                case SurfaceBindPropertyKind.PreBindOptions:

                    this.SurfaceProperties.BindProperties.PreBindOptions = (PreBindOptions)value;
                    break;

                case SurfaceBindPropertyKind.PostBindExistingOptions:

                    this.SurfaceProperties.BindProperties.PostBindExistingOptions = (PostBindExistingOptions)value;
                    break;

                case SurfaceBindPropertyKind.PostBindNewOptions:

                    this.SurfaceProperties.BindProperties.PostBindNewOptions = (PostBindNewOptions)value;
                    break;

                case SurfaceBindPropertyKind.BindState:
                    break;
                default:
                    Debugger.Break();
                    break;
            }
        }

		public override bool ShouldSerializeValue(object component)
		{
			return false;
		}

		public override string Category
		{
			get
			{
				return "Surface Properties";
			}
		}

		public override string DesignComments
		{
			get
			{
				return "Shows the hidden field names\r\nAlthough these properties exists at the selected object's type you cannot see them as editable";
			}
		}
    }
}
